<!-- 表单 》 输入框 -->

<template>
  <el-form-item v-bind="formItem">
    <!-- 标签 -->
    <template v-if="hasLabelSlot" #label>
      <slot name="label" :label="formItem.label">{{ formItem.label }}</slot>
    </template>

    <el-input
      v-if="lazy"
      v-model.lazy="model"
      v-bind="commonProps"
      :maxlength="max"
      :type="number ? 'number' : null"
      @change="toChange"
      @blur="toBlur"
      @keyup.enter.native="toEnter"
    >
      <!-- 前缀 -->
      <template v-if="hasPrefix" #prepend>
        <slot name="prefix">{{ prefix }}</slot>
      </template>

      <!-- 后缀 -->
      <template v-if="hasSuffix" #append>
        <slot name="suffix">{{ suffix }}</slot>
      </template>
    </el-input>

    <el-input
      v-else
      v-model="model"
      v-bind="commonProps"
      :maxlength="max"
      :type="number ? 'number' : null"
      @input="emitChange"
      @change="toChange"
      @blur="toBlur"
      @keyup.enter.native="toEnter"
    >
      <!-- 前缀 -->
      <template v-if="hasPrefix" #prepend>
        <slot name="prefix">{{ prefix }}</slot>
      </template>

      <!-- 后缀 -->
      <template v-if="hasSuffix" #append>
        <slot name="suffix">{{ suffix }}</slot>
      </template>
    </el-input>
  </el-form-item>
</template>

<script>
// ============================== 导入依赖 ============================== //

import CORE from '@/CORE'
import mixForm from '../mixForm'

const name = 'FormInput'

// ============================== 导出组件 ============================== //

export default {
  /**
   * 名称定义 (实际使用名称)
   */
  name,

  /**
   * 混入列表 (配置选项合并)
   */
  mixins: [mixForm],

  /**
   * 属性注册 (抽取以便查阅)
   */
  props: CORE.WEB[name],

  /**
   * 状态数据 (函数返回对象)
   */
  data() {
    return {
      model: '', // 内部绑定值
      EMPTY: '', // 空值常量
    }
  },

  /**
   * 计算属性 (慎用箭头函数)
   */
  computed: {
    /**
     * 是否有前缀
     */
    hasPrefix() {
      if (this.prefix) return true
      if (!this.$scopedSlots) return false
      return this.$scopedSlots.prefix
    },

    /**
     * 是否有后缀
     */
    hasSuffix() {
      if (this.suffix) return true
      if (!this.$scopedSlots) return false
      return this.$scopedSlots.suffix
    },
  },

  /**
   * 本地方法 (轻量重要在前)
   */
  methods: {
    /**
     * 是否不等 (可覆盖)
     */
    isDiff() {
      const { obj, prop, model, init, number, EMPTY } = this
      const value = obj[prop]

      // 纯数字
      if (number) {
        if (value === undefined) return model
        return value !== +model
      }

      // 无值
      if (!value) {
        if (model || init) return true
        return value !== EMPTY
      }

      // 有值
      return value !== model
    },

    /**
     * 设置内部绑定值 (可覆盖)
     */
    setModel() {
      const { obj, prop, init, number, EMPTY, upper, lower } = this

      if (number) { // 纯数字
        const value = obj[prop] === '' ? undefined : obj[prop]
        this.model = CORE.isNumber(value) ? value : CORE.isNumber(+value) ? value : undefined
      } else { // 字符串
        const value = obj[prop] || init || EMPTY
        this.model = upper ? value.toUpperCase() : lower ? value.toLowerCase() : value
      }
    },

    /**
     * 获取最终回传值 (可覆盖)
     */
    getValue() {
      const { model, number, upper, lower } = this
      if (number) return (model === '' || model === undefined) ? undefined : +model
      return upper ? model.toUpperCase() : lower ? model.toLowerCase() : model
    },

    /**
     * 改变事件
     */
    toChange() {
      if (!this.number) this.model = (this.model || '').trim()
      this.emitChange()
    },

    /**
     * 离开事件
     */
    async toBlur() {
      const { model, number } = this
      if (number && model !== '' && model !== undefined) {
        this.model = ''
        await this.$nextTick() // 修复输入 1. 时无法去掉 . 的bug
        this.model = +model
      }
      this.$emit('blur', this.model)
    },

    /**
     * 回车事件
     */
    toEnter() {
      this.$emit('enter', this.model)
    },
  },
}
</script>
